import fs from 'fs';
import path from 'path';
import { shell } from 'electron';
import logger from './logger';
import Result from './result';
import secureStore from './secureStore';
import si from 'systeminformation'; // 引入systeminformation

function isValidInstallPath(filePath) {
    // 获取下载目录
    const downloadDir = secureStore.getPlain('savePath');
    
    // 检查文件是否在下载目录中
    const resolvedPath = path.resolve(filePath);
    const resolvedDownloadDir = path.resolve(downloadDir);
    
    return resolvedPath.startsWith(resolvedDownloadDir);
}

// 通过进程名查找进程
async function findProcessByName(processName) {
    try {
        const processes = await si.processes();
        return processes.list.filter(p => 
            p.name && p.name.toLowerCase().includes(processName.toLowerCase())
        );
    } catch (error) {
        logger.error(`查找进程失败: ${error.message}`);
        return [];
    }
}

export default function InstallSoftware(_data, win) {
    return new Promise((resolve, reject) => {
        logger.info(`开始安装软件: ${JSON.stringify(_data)}`);
        
        // 安全检查
        if (!isValidInstallPath(_data.path)) {
            logger.error(`文件路径不合法: ${_data.path}`);
            return reject(Result.error(101, '文件路径不合法'));
        }
        
        if (!fs.existsSync(_data.path)) {
            logger.error(`安装文件不存在: ${_data.path}`);
            return reject(Result.error(101, `安装文件不存在: ${_data.path}`));
        }
        
        // 检查文件是否为空
        try {
            const stats = fs.statSync(_data.path);
            if (stats.size === 0) {
                logger.error(`安装文件为空: ${_data.path}`);
                return reject(Result.error(101, '安装文件为空'));
            }
        } catch (statError) {
            logger.error(`无法获取文件信息: ${statError.message}`);
            return reject(Result.error(101, '无法获取文件信息'));
        }
        
        // 获取文件扩展名
        const ext = path.extname(_data.path).toLowerCase();
        logger.info(`文件扩展名: ${ext}`);
        
        if (ext === '.msi') {
            // MSI文件处理 - 增强版本
            logger.info(`启动MSI安装: ${_data.path}`);
            
            // 检查文件是否为有效的MSI文件
            const { exec } = require('child_process');
            exec(`msiexec /q /i "${_data.path}"`, (error, stdout, stderr) => {
                if (error) {
                    // 忽略错误，因为我们只是检查文件有效性
                    logger.info(`MSI文件检查完成`);
                }
                
                // 检查stderr中是否包含错误信息
                if (stderr && stderr.includes('无法打开此安装程序包')) {
                    logger.error(`MSI文件无效或损坏: ${_data.path}`);
                    // 通知前端安装失败
                    if (win && !win.isDestroyed()) {
                        win.webContents.send('install-status', { 
                            id: _data.id, 
                            status: 'failed', 
                            error: 'MSI文件无效或损坏，请重新下载' 
                        });
                    }
                    return reject(Result.error(101, 'MSI文件无效或损坏'));
                }
                
                // 文件有效，开始真正的安装
                const { spawn } = require('child_process');
                logger.info(`启动MSI安装: msiexec /i "${_data.path}"`);
                const child = spawn('msiexec', ['/i', _data.path], {
                    detached: true,
                    stdio: 'ignore'
                });
                
                // 通知前端安装已启动
                if (win && !win.isDestroyed()) {
                    win.webContents.send('install-status', { id: _data.id, status: 'started' });
                }
                
                child.on('close', (code) => {
                    logger.info(`MSI安装进程关闭，退出码: ${code}`);
                    if (code === 0) {
                        logger.info(`MSI安装成功: ${_data.path}`);
                        // 通知前端安装完成
                        if (win && !win.isDestroyed()) {
                            win.webContents.send('install-status', { id: _data.id, status: 'completed' });
                        }
                        resolve(Result.success());
                    } else {
                        const errorMsg = code === null ? 
                            `MSI安装被用户取消` : 
                            `MSI安装失败，退出码: ${code}`;
                        logger.error(errorMsg);
                        // 通知前端安装失败
                        if (win && !win.isDestroyed()) {
                            win.webContents.send('install-status', { 
                                id: _data.id, 
                                status: 'failed', 
                                error: errorMsg
                            });
                        }
                        resolve(Result.success());
                    }
                });
                
                child.on('error', (error) => {
                    logger.error(`MSI安装启动失败: ${error.message}`);
                    // 通知前端安装失败
                    if (win && !win.isDestroyed()) {
                        win.webContents.send('install-status', { 
                            id: _data.id, 
                            status: 'failed', 
                            error: `MSI安装启动失败: ${error.message}` 
                        });
                    }
                    resolve(Result.success());
                });
            });
        } else if (ext === '.exe') {
            // EXE文件处理 - 使用systeminformation监控进程
            logger.info(`尝试启动EXE安装: ${_data.path}`);
            
            // 获取不带扩展名的文件名，用于进程监控
            const fileName = path.basename(_data.path, '.exe');
            logger.info(`将监控进程名: ${fileName}`);
            
            // 记录初始文件状态
            let initialFileExists = true;
            
            // 首先尝试使用shell.openPath（推荐方法）
            shell.openPath(_data.path)
                .then(() => {
                    logger.info(`使用shell.openPath成功启动安装: ${_data.path}`);
                    // 通知前端安装已启动
                    if (win && !win.isDestroyed()) {
                        win.webContents.send('install-status', { id: _data.id, status: 'started' });
                    }
                    
                    // 使用systeminformation监控进程
                    let checkCount = 0;
                    const maxChecks = 120; // 最多检查20分钟（每10秒检查一次）
                    let installProcessFound = false;
                    let monitoringActive = true;
                    
                    const monitorInstallation = async () => {
                        try {
                            // 检查监控是否仍处于活动状态
                            if (!monitoringActive) {
                                return;
                            }
                            
                            checkCount++;
                            logger.info(`检查安装进程状态 (${checkCount}/${maxChecks}): ${fileName}`);
                            
                            if (checkCount > maxChecks) {
                                // 超时，假设安装已完成或被取消
                                logger.info(`安装进程监控超时: ${fileName}`);
                                monitoringActive = false;
                                if (win && !win.isDestroyed()) {
                                    win.webContents.send('install-status', { 
                                        id: _data.id, 
                                        status: 'completed',
                                        message: '安装监控超时，安装可能已完成' 
                                    });
                                }
                                return;
                            }
                            
                            // 检查安装文件是否仍然存在
                            if (!fs.existsSync(_data.path)) {
                                initialFileExists = false;
                                logger.info(`安装文件已被删除: ${_data.path}`);
                            }
                            
                            // 查找相关进程
                            const processes = await findProcessByName(fileName);
                            
                            if (processes.length > 0) {
                                installProcessFound = true;
                                logger.info(`发现安装相关进程: ${processes.length} 个`);
                                processes.forEach(p => {
                                    logger.info(`进程: ${p.name} (PID: ${p.pid}, CPU: ${p.cpu}, MEM: ${p.mem})`);
                                });
                                // 进程仍在运行，继续监控
                                setTimeout(monitorInstallation, 5000); // 5秒后再次检查
                            } else if (installProcessFound) {
                                // 之前发现过进程，现在没有了，说明安装已完成
                                logger.info(`安装进程已结束: ${fileName}`);
                                monitoringActive = false;
                                if (win && !win.isDestroyed()) {
                                    win.webContents.send('install-status', { id: _data.id, status: 'completed' });
                                }
                            } else {
                                // 检查文件是否被删除且从未发现进程，可能是用户取消了安装
                                if (!initialFileExists) {
                                    logger.info(`安装文件已被删除且未发现相关进程，用户可能取消了安装: ${fileName}`);
                                    monitoringActive = false;
                                    if (win && !win.isDestroyed()) {
                                        win.webContents.send('install-status', { 
                                            id: _data.id, 
                                            status: 'failed', 
                                            error: '用户可能取消了安装或文件已被删除' 
                                        });
                                    }
                                    return;
                                }
                                
                                // 还没发现进程，可能是启动延迟，继续检查
                                logger.info(`尚未发现安装进程，继续监控: ${fileName}`);
                                setTimeout(monitorInstallation, 5000); // 5秒后再次检查
                            }
                        } catch (error) {
                            logger.error(`监控安装进程时出错: ${error.message}`);
                            setTimeout(monitorInstallation, 5000); // 出错也继续监控
                        }
                    };
                    
                    // 开始监控
                    setTimeout(monitorInstallation, 5000); // 5秒后开始第一次检查
                    
                    resolve(Result.success());
                })
                .catch(shellError => {
                    logger.error(`shell.openPath失败: ${shellError.message}`);
                    // 通知前端安装失败
                    if (win && !win.isDestroyed()) {
                        win.webContents.send('install-status', { 
                            id: _data.id, 
                            status: 'failed', 
                            error: `启动安装程序失败: ${shellError.message}` 
                        });
                    }
                    resolve(Result.success());
                });
        } else {
            // 其他文件类型使用系统默认程序打开
            logger.info(`打开文件: ${_data.path}`);
            shell.openPath(_data.path)
                .then(() => {
                    // 通知前端文件已打开
                    if (win && !win.isDestroyed()) {
                        win.webContents.send('install-status', { id: _data.id, status: 'opened' });
                    }
                    resolve(Result.success());
                })
                .catch(error => {
                    logger.error(`文件打开失败: ${error.message}`);
                    // 通知前端操作失败
                    if (win && !win.isDestroyed()) {
                        win.webContents.send('install-status', { 
                            id: _data.id, 
                            status: 'failed', 
                            error: error.message 
                        });
                    }
                    resolve(Result.success());
                });
        }
    });
}